package message.handler;

import message.annotation.MsgHandler;
import message.utils.StringUtils;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@MsgHandler(name = "fixed")
public class FixedHandler extends BaseHandler {

    StringBuffer resultSbf = new StringBuffer();
    String unPackMessageInfo = "";
    int currentIndex = 0;
    int msgLength = 0;

    @Override
    protected void doPack(Map source) throws Exception {

        packDataToMap(this.msgConfig.getDocumentElement(), null, source);

        this.msgData = resultSbf.toString().getBytes(this.msgConfig.getEncoding());
    }

    @Override
    protected void doUnPack(byte[] rspByte) throws Exception {
        // TODO:如果报文长度使用字节长度，此位置可修改为字节数组，拆分是拆字节数组转换成字符串
        this.unPackMessageInfo = new String(rspByte, this.msgConfig.getEncoding());
        this.msgLength = unPackMessageInfo.length();
        Map result = new HashMap();
        unPackDataToMap(this.msgConfig.getDocumentElement(), result, null);
        this.unPackResult = result;

    }


    @Override
    public void packInit() {

    }

    @Override
    public void unPackInit() {

    }

    protected void packFiled(Map<String, String> elementAttr, List<Element> elements, Map data, Map source) {
        Object value = getValueForSource(elementAttr.get("expression"), source);

        Object s = invokeMethod(elements, value == null ? "" : value.toString());

        this.resultSbf.append(s);
    }

    protected void packMap(Map<String, String> elementAttr, List<Element> elements, Map data, Map source) {
        elements.forEach((ele) -> {
            packDataToMap(ele, null, source);
        });
    }

    protected void packList(Map<String, String> elementAttr, List<Element> elements, Map data, Map source) {
        Object childSource = getValueForSource(elementAttr.get("expression"), source);
        // 获取循环次数， 先取固定值，固定值没有取表达式，表达式在没有报错；
        String loopTims = elementAttr.get("loopTims");
        if (loopTims == null || "".equals(loopTims.trim())) {
            Object loopTimsValue = getValueForSource(elementAttr.get("loopTimsExpression"), source);
            if (loopTimsValue == null || "".equals(loopTimsValue)) {
                System.err.println("循环次数获取异常，无固定值，表达式取值未取到");
                return;
            }
            loopTims = loopTimsValue.toString().trim();
        }
        int loopTim = Integer.parseInt(loopTims);

        for (int i = 0; i < loopTim; i++) {
            // 取当前循环的取值容器
            Map oneChildSource = !(childSource instanceof List) || ((List) childSource).size() <= i
                    ? new HashMap() : (Map) ((List) childSource).get(i);
            elements.forEach((ele) -> {
                packDataToMap(ele, null, (Map) oneChildSource);
            });
        }
    }

    protected void unPackFiled(Map<String, String> elementAttr, Map data, Map source, List<Element> elements) {
        int length = Integer.parseInt(elementAttr.get("length"));
        Object result = this.unPackMessageInfo.substring(currentIndex, currentIndex += length);
        if (null != elements) {
            result = invokeMethod(elements, result);
        }
        putValue(elementAttr.get("expression"), result, data);
    }

    protected void unPackList(Map<String, String> elementAttr, List<Element> elements, Map data, Map source) {
        List childDataList = new ArrayList();
        putValue(elementAttr.get("expression"), childDataList, data);

        String loopTims = elementAttr.get("loopTims");
        if (loopTims == null || loopTims.isEmpty()) {
            String loopTimsExpression = elementAttr.get("loopTimsExpression");
            Object valueForSource = getValueForSource(loopTimsExpression, data);
            if (valueForSource != null && !valueForSource.toString().isEmpty()) {
                loopTims = (String) valueForSource;
            } else {
                System.err.println("定长【" + elementAttr.get("name") + "】节点报文拆包异常，未获取到循环节点循环次数");
            }
        }
        int loopTim = Integer.parseInt(loopTims);
        if (loopTim == -1) {

        }
        for (int i = 0; loopTim == -1 || i < loopTim; i++) {
            Map sunData = new HashMap();
            elements.forEach((ele) -> {
                unPackDataToMap(ele, sunData, null);
            });
            childDataList.add(sunData);
        }


//        ((List) childSource).forEach(oneChildSource -> {
//                    Map sunData = new HashMap();
//                    elements.forEach((ele) -> {
//                        unPackDataToMap(ele, sunData, (Map) oneChildSource);
//                    });
//                    childDataList.add(sunData);
//                }
//        );
    }
}
